﻿using log4net;
using SharpML.Api.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace SharpML.Gui.Extensions
{
    public static class Controls
    {
        public static void AsyncGuiOp( this Control control, Action action )
        {
            // Async Invoke on UI thread (because you can deadlock if you don't follow the pattern)
            Action async = delegate {

                // Failsafe, the window may go away if something went seriously wrong
                // No need to add insult to injury
                try { control.Invoke( action ); }

                // Log operations are async, so can't log here, send to console as last resort
                catch( Exception exception ) { System.Console.Write( exception.ToString() ); }
            };

            // Set it, and forget it
            async.BeginInvoke( null, null );
        }

        public static void AsyncOp( this Control control, Action action )
        {
            // Async Invoke on UI thread (because you can deadlock if you don't follow the pattern)
            Action async = delegate
            {

                // Failsafe, the window may go away if something went seriously wrong
                // No need to add insult to injury
                try { action(); }

                // Ignore, nowhere to log
                catch( Exception exception ) { LogManager.GetLogger( control.GetType() ).Error( "Asyncronous operation failed", exception ); }
            };

            // Set it, and forget it
            async.BeginInvoke( null, null );
        }

        public static void OffThread( this Control control, Action action )
        {
            // Async Invoke on UI thread (because you can deadlock if you don't follow the pattern)
            Action async = delegate
            {

                // Failsafe, the window may go away if something went seriously wrong
                // No need to add insult to injury
                try { action(); }

                // Ignore, nowhere to log
                catch( Exception exception ) { LogManager.GetLogger( control.GetType() ).Error( "Asyncronous operation failed", exception ); }
            };

            // Set it, and wait for it
            var state = async.BeginInvoke( null, null );

            while( !state.IsCompleted )
                Thread.CurrentThread.PumpYieldAll( Application.DoEvents );

        }
    }
}
